/*
 * Copyright (c) 2020-2024 Huawei Cloud Computing Technology Co., Ltd. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this list of
 *    conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
 *    of conditions and the following disclaimer in the documentation and/or other materials
 *    provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
 *    to endorse or promote products derived from this software without specific prior written
 *    permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "calculate.h"
#include "mqtt_client_entry.h"
#include "bmsinfo.h"
#include "common.h"


#define SOC_TABLE_MAX       96
#define SOC_TAB_TEMPE_MAX   7

// SOC, -20℃,-10℃,0℃,10℃,20℃,30℃,40℃
const float BattTempeTab[SOC_TAB_TEMPE_MAX] = {
    -20.0f, -10.0f, 0.0f, 10.0f, 20.0f, 30.0f, 40.0f
};

const float SocVotTab[SOC_TABLE_MAX][SOC_TAB_TEMPE_MAX] = {
    /* 0%*/ 3.584f, 3.533f, 3.498f, 3.466f, 3.426f, 3.367f, 3.282f,
    /* 1%*/ 3.587f, 3.539f, 3.507f, 3.476f, 3.438f, 3.384f, 3.309f,
    /* 2%*/ 3.590f, 3.546f, 3.514f, 3.485f, 3.449f, 3.400f, 3.334f,
    /* 3%*/ 3.593f, 3.551f, 3.522f, 3.493f, 3.460f, 3.415f, 3.357f,
    /* 4%*/ 3.596f, 3.557f, 3.528f, 3.501f, 3.470f, 3.430f, 3.378f, 
    /* 5%*/ 3.598f, 3.562f, 3.535f, 3.509f, 3.480f, 3.443f, 3.398f,
    /* 6%*/ 3.601f, 3.567f, 3.541f, 3.516f, 3.489f, 3.456f, 3.417f,
    /* 7%*/ 3.604f, 3.571f, 3.546f, 3.523f, 3.498f, 3.468f, 3.434f,
    /* 8%*/ 3.606f, 3.575f, 3.552f, 3.530f, 3.506f, 3.479f, 3.449f,
    /* 9%*/ 3.609f, 3.579f, 3.557f, 3.536f, 3.513f, 3.489f, 3.464f,
    /*10%*/ 3.612f, 3.583f, 3.561f, 3.541f, 3.521f, 3.498f, 3.477f,
    /*11%*/ 3.614f, 3.586f, 3.566f, 3.547f, 3.528f, 3.507f, 3.489f,
    /*12%*/ 3.617f, 3.590f, 3.570f, 3.552f, 3.534f, 3.516f, 3.500f,
    /*13%*/ 3.619f, 3.593f, 3.574f, 3.557f, 3.540f, 3.524f, 3.510f,
    /*14%*/ 3.622f, 3.596f, 3.578f, 3.562f, 3.546f, 3.531f, 3.520f,
    /*15%*/ 3.625f, 3.599f, 3.581f, 3.566f, 3.552f, 3.538f, 3.528f,
    /*16%*/ 3.627f, 3.602f, 3.584f, 3.570f, 3.557f, 3.544f, 3.536f,
    /*17%*/ 3.630f, 3.604f, 3.588f, 3.574f, 3.562f, 3.550f, 3.543f,
    /*18%*/ 3.633f, 3.607f, 3.591f, 3.578f, 3.567f, 3.556f, 3.549f,
    /*19%*/ 3.636f, 3.610f, 3.594f, 3.582f, 3.571f, 3.561f, 3.555f,
    /*20%*/ 3.639f, 3.612f, 3.597f, 3.586f, 3.576f, 3.566f, 3.561f,
    /*21%*/ 3.642f, 3.615f, 3.600f, 3.589f, 3.580f, 3.571f, 3.566f,
    /*22%*/ 3.645f, 3.618f, 3.603f, 3.593f, 3.584f, 3.576f, 3.571f,
    /*23%*/ 3.648f, 3.620f, 3.605f, 3.596f, 3.588f, 3.580f, 3.575f,
    /*24%*/ 3.652f, 3.623f, 3.608f, 3.599f, 3.592f, 3.584f, 3.579f,
    /*25%*/ 3.655f, 3.626f, 3.611f, 3.602f, 3.595f, 3.588f, 3.583f,
    /*26%*/ 3.659f, 3.629f, 3.614f, 3.606f, 3.599f, 3.592f, 3.586f,
    /*27%*/ 3.662f, 3.631f, 3.617f, 3.609f, 3.602f, 3.595f, 3.590f,
    /*28%*/ 3.666f, 3.634f, 3.619f, 3.612f, 3.606f, 3.599f, 3.593f,
    /*29%*/ 3.670f, 3.637f, 3.622f, 3.615f, 3.609f, 3.602f, 3.596f,
    /*30%*/ 3.674f, 3.641f, 3.625f, 3.618f, 3.613f, 3.606f, 3.599f,
    /*31%*/ 3.678f, 3.644f, 3.628f, 3.621f, 3.616f, 3.609f, 3.602f,
    /*32%*/ 3.682f, 3.647f, 3.632f, 3.625f, 3.619f, 3.613f, 3.605f,
    /*33%*/ 3.687f, 3.651f, 3.635f, 3.628f, 3.623f, 3.616f, 3.608f,
    /*34%*/ 3.691f, 3.654f, 3.638f, 3.631f, 3.626f, 3.619f, 3.611f,
    /*35%*/ 3.696f, 3.658f, 3.641f, 3.635f, 3.630f, 3.623f, 3.615f,
    /*36%*/ 3.700f, 3.662f, 3.645f, 3.638f, 3.633f, 3.626f, 3.618f,
    /*37%*/ 3.705f, 3.666f, 3.649f, 3.642f, 3.637f, 3.630f, 3.621f,
    /*38%*/ 3.710f, 3.670f, 3.653f, 3.646f, 3.641f, 3.634f, 3.624f,
    /*39%*/ 3.715f, 3.674f, 3.656f, 3.649f, 3.645f, 3.637f, 3.628f,
    /*40%*/ 3.720f, 3.679f, 3.660f, 3.653f, 3.648f, 3.641f, 3.632f,
    /*41%*/ 3.725f, 3.683f, 3.665f, 3.657f, 3.652f, 3.645f, 3.636f,
    /*42%*/ 3.731f, 3.688f, 3.669f, 3.662f, 3.657f, 3.649f, 3.640f,
    /*43%*/ 3.736f, 3.693f, 3.674f, 3.666f, 3.661f, 3.654f, 3.644f,
    /*44%*/ 3.742f, 3.698f, 3.678f, 3.670f, 3.665f, 3.658f, 3.648f,
    /*45%*/ 3.748f, 3.703f, 3.683f, 3.675f, 3.670f, 3.663f, 3.653f,
    /*46%*/ 3.753f, 3.709f, 3.688f, 3.680f, 3.675f, 3.667f, 3.658f,
    /*47%*/ 3.759f, 3.714f, 3.694f, 3.685f, 3.679f, 3.672f, 3.663f,
    /*48%*/ 3.765f, 3.720f, 3.699f, 3.690f, 3.685f, 3.677f, 3.668f,
    /*49%*/ 3.772f, 3.726f, 3.705f, 3.696f, 3.690f, 3.683f, 3.674f,
    /*50%*/ 3.778f, 3.732f, 3.711f, 3.701f, 3.695f, 3.688f, 3.679f,
    /*51%*/ 3.784f, 3.738f, 3.716f, 3.707f, 3.701f, 3.694f, 3.685f,
    /*52%*/ 3.791f, 3.745f, 3.723f, 3.713f, 3.707f, 3.700f, 3.691f,
    /*53%*/ 3.797f, 3.751f, 3.729f, 3.719f, 3.713f, 3.706f, 3.698f,
    /*54%*/ 3.804f, 3.758f, 3.735f, 3.725f, 3.719f, 3.712f, 3.704f,
    /*55%*/ 3.810f, 3.765f, 3.742f, 3.732f, 3.725f, 3.718f, 3.711f,
    /*56%*/ 3.817f, 3.772f, 3.749f, 3.738f, 3.732f, 3.725f, 3.718f,
    /*57%*/ 3.824f, 3.779f, 3.756f, 3.745f, 3.738f, 3.732f, 3.725f,
    /*58%*/ 3.831f, 3.786f, 3.764f, 3.752f, 3.745f, 3.739f, 3.733f,
    /*59%*/ 3.838f, 3.794f, 3.771f, 3.760f, 3.753f, 3.746f, 3.741f,
    /*60%*/ 3.845f, 3.801f, 3.779f, 3.767f, 3.760f, 3.754f, 3.748f,
    /*61%*/ 3.853f, 3.809f, 3.786f, 3.775f, 3.768f, 3.762f, 3.756f,
    /*62%*/ 3.860f, 3.817f, 3.794f, 3.783f, 3.775f, 3.770f, 3.765f,
    /*63%*/ 3.867f, 3.825f, 3.803f, 3.791f, 3.784f, 3.778f, 3.773f,
    /*64%*/ 3.875f, 3.833f, 3.811f, 3.799f, 3.792f, 3.786f, 3.782f,
    /*65%*/ 3.882f, 3.842f, 3.820f, 3.807f, 3.800f, 3.795f, 3.791f,
    /*66%*/ 3.890f, 3.850f, 3.828f, 3.816f, 3.809f, 3.803f, 3.800f,
    /*67%*/ 3.898f, 3.859f, 3.837f, 3.825f, 3.818f, 3.812f, 3.809f,
    /*68%*/ 3.905f, 3.867f, 3.846f, 3.834f, 3.827f, 3.821f, 3.818f,
    /*69%*/ 3.913f, 3.876f, 3.855f, 3.843f, 3.836f, 3.831f, 3.827f,
    /*70%*/ 3.921f, 3.885f, 3.865f, 3.853f, 3.845f, 3.840f, 3.837f,
    /*71%*/ 3.929f, 3.894f, 3.874f, 3.862f, 3.855f, 3.850f, 3.847f,
    /*72%*/ 3.937f, 3.903f, 3.884f, 3.872f, 3.865f, 3.860f, 3.857f,
    /*73%*/ 3.945f, 3.913f, 3.893f, 3.882f, 3.875f, 3.870f, 3.867f,
    /*74%*/ 3.953f, 3.922f, 3.903f, 3.892f, 3.885f, 3.880f, 3.877f,
    /*75%*/ 3.962f, 3.931f, 3.913f, 3.902f, 3.895f, 3.890f, 3.887f,
    /*76%*/ 3.970f, 3.941f, 3.923f, 3.912f, 3.906f, 3.901f, 3.897f,
    /*77%*/ 3.978f, 3.950f, 3.933f, 3.923f, 3.916f, 3.911f, 3.908f,
    /*78%*/ 3.987f, 3.960f, 3.944f, 3.933f, 3.927f, 3.922f, 3.919f,
    /*79%*/ 3.995f, 3.970f, 3.954f, 3.944f, 3.938f, 3.933f, 3.929f,
    /*80%*/ 4.004f, 3.980f, 3.964f, 3.955f, 3.949f, 3.944f, 3.940f,
    /*81%*/ 4.012f, 3.990f, 3.975f, 3.966f, 3.960f, 3.955f, 3.951f,
    /*82%*/ 4.021f, 4.000f, 3.986f, 3.977f, 3.971f, 3.967f, 3.962f,
    /*83%*/ 4.030f, 4.010f, 3.996f, 3.988f, 3.982f, 3.978f, 3.973f,
    /*84%*/ 4.039f, 4.020f, 4.007f, 3.999f, 3.994f, 3.990f, 3.985f,
    /*85%*/ 4.048f, 4.030f, 4.018f, 4.010f, 4.005f, 4.001f, 3.996f,
    /*86%*/ 4.057f, 4.040f, 4.029f, 4.021f, 4.017f, 4.013f, 4.008f,
    /*87%*/ 4.066f, 4.050f, 4.040f, 4.033f, 4.028f, 4.025f, 4.019f,
    /*88%*/ 4.075f, 4.061f, 4.050f, 4.044f, 4.040f, 4.036f, 4.031f,
    /*89%*/ 4.085f, 4.071f, 4.061f, 4.055f, 4.051f, 4.048f, 4.043f,
    /*90%*/ 4.094f, 4.082f, 4.072f, 4.066f, 4.063f, 4.060f, 4.055f,
    /*91%*/ 4.104f, 4.092f, 4.083f, 4.079f, 4.076f, 4.073f, 4.067f,
    /*92%*/ 4.114f, 4.102f, 4.094f, 4.090f, 4.088f, 4.085f, 4.080f,
    /*93%*/ 4.124f, 4.113f, 4.105f, 4.101f, 4.099f, 4.097f, 4.092f,
    /*94%*/ 4.134f, 4.123f, 4.116f, 4.113f, 4.111f, 4.109f, 4.105f,
    /*95%*/ 4.144f, 4.134f, 4.127f, 4.124f, 4.123f, 4.122f, 4.11f ,
};

/**
 * @brief 
 * 
 */
void modify_BmsInfoCellVolt(void)
{
    uint16_t i = 0, board_index;
    _SystemDataStru *bmsInf = getBmsInf();

    for (board_index = 0; board_index < BMU_OF_NUM; board_index++)
    {
        for (i = 0; i < CELL_NUM_PER_UINT; i ++)
        {
            bmsInf->bmu[board_index].voltage[i].Bit.VcellVal = 3700 + rand()%300;
        }
    }
}

/**
 * @brief 
 * 
 */
void modify_BmsInfoCellTempe(void)
{
    uint16_t i = 0, board_index;
    _SystemDataStru *bmsInf = getBmsInf();

    for (board_index = 0; board_index < BMU_OF_NUM; board_index++) // 点位 600 - 620
    {
        for (i = 0; i < TEMP_NUM_PER_UINT; i ++)
        {
            bmsInf->bmu[board_index].temprature[i] = 23.6f + ((float)(rand()%1000) / 100.0f);
        }
    }
}


/*******************************************************************************
* FunctionName   : void maxMinCellVol(void)
* Description    : 计算电池最小最大单体电压
* EntryParameter : None
* ReturnValue    : None
*******************************************************************************/
void maxMinCellVol(void)
{
    uint16_t borad_index, i, iValidCellNum;
    MAX_MIN_ID_t Vmax_ID;
    MAX_MIN_ID_t Vmin_ID;
   
    uint16_t Vmax = 0;
    uint16_t Vmin = 0xFFFF;
    uint32_t sum = 0;
    Vmax_ID.allbits=0;
    Vmin_ID.allbits=0;
    _SystemDataStru *bmsInf = getBmsInf();

    iValidCellNum = 0;
    for (borad_index = 0; borad_index < (BMU_OF_NUM); borad_index++)
    {
        for (i = 0; i < CELL_NUM_PER_UINT; i++)
        {
            if (0 == bmsInf->bmu[borad_index].voltage[i].Bit.valid)
            {
                continue;
            }
            iValidCellNum ++;
            
            sum += bmsInf->bmu[borad_index].voltage[i].Bit.VcellVal;
            if (Vmax <= bmsInf->bmu[borad_index].voltage[i].Bit.VcellVal)
            {
                Vmax = bmsInf->bmu[borad_index].voltage[i].Bit.VcellVal;
                Vmax_ID.Bit.bmu_id=borad_index;
                Vmax_ID.Bit.bmu_index=i;
            }
            if (Vmin > bmsInf->bmu[borad_index].voltage[i].Bit.VcellVal)
            {
                Vmin = bmsInf->bmu[borad_index].voltage[i].Bit.VcellVal;
                Vmin_ID.Bit.bmu_id=borad_index;
                Vmin_ID.Bit.bmu_index=i;
            }
        }
    }

    if (0 == iValidCellNum)
    {
        return;
    }
    bmsInf->battery_total_vol_cell_sum = sum / 100; /*计算电池总压,系数0.1*/
    bmsInf->VAvg_Cell = sum / iValidCellNum;
    bmsInf->Vdelta_Cell = (Vmax - Vmin);
    bmsInf->VcellMax = Vmax;
    bmsInf->VcellMin = Vmin;

    bmsInf->VcellMaxID.Bit.bmu_id = Vmax_ID.Bit.bmu_id + 1;
    bmsInf->VcellMaxID.Bit.bmu_index= Vmax_ID.Bit.bmu_index + 1;
    bmsInf->VcellMinID.Bit.bmu_id = Vmin_ID.Bit.bmu_id + 1;
    bmsInf->VcellMinID.Bit.bmu_index= Vmin_ID.Bit.bmu_index + 1;
    bmsInf->vol_valid_num = iValidCellNum;
}

/*******************************************************************************
* FunctionName   : void maxMinTemp(void)
* Description    : 计算温度的电池最大、最小温度
* EntryParameter : None
* ReturnValue    : None
*******************************************************************************/
void maxMinTemp(void)
{
    _SystemDataStru *bmsInf = getBmsInf();

    uint16_t borad_index, i, iValidTempNum;
    MAX_MIN_ID_t TmaxID;
    MAX_MIN_ID_t TminID;
    float Tmax = bmsInf->bmu[0].temprature[0];
    float Tmin = Tmax;
    static float Tsum = 0.0f;
    TminID.allbits = 0;
    TmaxID.allbits =0;

    iValidTempNum = 0;
    Tsum = 0.0f;
    for (borad_index = 0; borad_index < (BMU_OF_NUM); borad_index++)
    {
        for (i = 0; i < TEMP_NUM_PER_UINT; i++)  
        {
            if (0 == bmsInf->bmu[borad_index].tempratureCaliVal[i].Bit.valid)
            {
                bmsInf->bmu[borad_index].temprature[i]= MIN_VALID_TEMP_VALUE; 
                DebugInfo("[long] unused Tempe : %d-%d\n", borad_index, i);
                continue;
            }
            iValidTempNum ++;

            Tsum += bmsInf->bmu[borad_index].temprature[i];
            if (Tmax < bmsInf->bmu[borad_index].temprature[i])
            {
                Tmax = bmsInf->bmu[borad_index].temprature[i];
                TmaxID.Bit.bmu_index = i;
                TmaxID.Bit.bmu_id = borad_index;
            }
            if (Tmin > bmsInf->bmu[borad_index].temprature[i])
            {
                Tmin = bmsInf->bmu[borad_index].temprature[i];
                TminID.Bit.bmu_index = i;
                TminID.Bit.bmu_id = borad_index;
            }
        }
    }
    // printf("\r[long] Tsum=%f; iValidTempNum=%d\n", Tsum, iValidTempNum);
    if (0 == iValidTempNum)
    {
        bmsInf->Tmax = 0xFFFF;
        bmsInf->Tmin = 0xFFFF;       
        return;
    }
    bmsInf->Tcell_avg = Tsum / iValidTempNum;
    bmsInf->Tmax = Tmax;
    bmsInf->Tmin = Tmin;  
    bmsInf->deltaT = Tmax - Tmin;
    bmsInf->Tmax_ID.Bit.bmu_id= TmaxID.Bit.bmu_id+1;
    bmsInf->Tmax_ID.Bit.bmu_index= TmaxID.Bit.bmu_index+1;
    bmsInf->Tmin_ID.Bit.bmu_id= TminID.Bit.bmu_id+1;
    bmsInf->Tmin_ID.Bit.bmu_index= TminID.Bit.bmu_index+1;
    bmsInf->temp_valid_num = iValidTempNum;

}


/**
 * @brief 
 * 
 * @param a 
 * @param b 
 * @return float 
 */
float api_cap_abs(float a, float b)
{
    if(a > b)   return a-b;
    else    return b-a;
}

/**
 * @brief 
 * 
 * @param avg_volt 
 * @return float 
 */
float api_calculate_soc_index(float avg_volt, float avg_tempe)
{
    float ret_soc = 0.0f;
    float socDecimals = 0.0f;
    float diffvalue = 0.0f;
    static uint8_t index_tempe = 0;
    static uint8_t index_Volt = 0;
    uint8_t i = 0;

    diffvalue = api_cap_abs(avg_tempe, BattTempeTab[index_tempe]);

    // 计算最接近的温度值
    for(i = 0; i < 7; i ++)
    {
        if(diffvalue > api_cap_abs(avg_tempe, BattTempeTab[i]))
        {
            diffvalue = api_cap_abs(avg_tempe, BattTempeTab[i]);
            index_tempe = i;
        }
    }

    diffvalue = api_cap_abs(avg_volt, SocVotTab[0][index_tempe]);
    ret_soc = 0.0f;
    
    for(i = 0; i < SOC_TABLE_MAX; i ++)
    {
        if(diffvalue > api_cap_abs(avg_volt, SocVotTab[i][index_tempe]))
        {
            diffvalue = api_cap_abs(avg_volt, SocVotTab[i][index_tempe]);
            index_Volt = i;
            ret_soc = (float) i;
        }
    }
    if (index_Volt < SOC_TABLE_MAX)
    {
        socDecimals = (avg_volt - SocVotTab[index_Volt][index_tempe]) 
            / ((SocVotTab[index_Volt + 1][index_tempe] - SocVotTab[index_Volt][index_tempe]));
        // DebugInfo("\r[long] socDecimals = %f\n", socDecimals);
    }
    return (ret_soc + socDecimals);
}

/**
 * @brief 
 * 
 */
void calculate_soc(void)
{
    _SystemDataStru *bmsInf = getBmsInf();
    bmsInf->SOC = api_calculate_soc_index(bmsInf->VAvg_Cell/1000.0f, bmsInf->Tcell_avg);
    // DebugInfo("\r[long] cal  soc = %f  avg_V=%d  avg_T=%f\n", bmsInf->SOC, bmsInf->VAvg_Cell, bmsInf->Tcell_avg);
}

 
/**
  * @brief  检测总压过高或过低
  * @attention 运行周期 50ms
  * @retval 无
**/
void check_pack_vol_alarm_task(void)
{
    _SystemDataStru *bmsInf = getBmsInf();

    if ((bmsInf-> battery_total_vol_cell_sum  > bmsInf->SysParamStru.chgPackVolWarningTHD)
             && (bmsInf->battery_total_vol_cell_sum  < bmsInf->SysParamStru.chgPackVolOpenTHD)
             && (bmsInf->sysAlarmStru.pack_ov != LEVEL1))
    {
        bmsInf->sysAlarmStru.pack_ov = LEVEL2;
    }
    else if ((bmsInf-> battery_total_vol_cell_sum  < bmsInf->SysParamStru. dsgPackVolWarningTHD)
             && (bmsInf-> battery_total_vol_cell_sum  > bmsInf->SysParamStru. dsgPackVolOpenTHD)
             && (bmsInf->sysAlarmStru.pack_uv != LEVEL1))
    {
 
        bmsInf->sysAlarmStru.pack_uv = LEVEL2;
    }
    else/*电压正常*/
    {
        if (bmsInf->sysAlarmStru.pack_ov == LEVEL2)  bmsInf->sysAlarmStru.pack_ov = NORMAL;
        if (bmsInf->sysAlarmStru.pack_uv == LEVEL2)  bmsInf->sysAlarmStru.pack_uv = NORMAL;

    }
}

/**
  * @brief  检测 电流过高或过低
  * @attention 运行周期50ms
  * @retval 无
**/
void check_I_alarm_task(void)
{
    _SystemDataStru *bmsInf = getBmsInf();

    if (bmsInf->workMode == MODE_CHG)/*充电过流检测*/
    {
        if ((bmsInf->I_system  > (bmsInf->SysParamStru.IpChgWarningTHD))
                 && (bmsInf->I_system < bmsInf->SysParamStru.Ip_ChgOpenTHD)
                 && (bmsInf->sysAlarmStru.chg_over_current != LEVEL1))   //充电告警
        {
            bmsInf->sysAlarmStru.chg_over_current = LEVEL2;
        }
        else/*充电过流正常处理*/
        {
            if (bmsInf->sysAlarmStru.chg_over_current == LEVEL2)
                bmsInf->sysAlarmStru.chg_over_current = NORMAL;
        }
    }
    else/*放电和故障状态检测*/
    {
        if ((bmsInf->I_system < - bmsInf->SysParamStru.Ip_DsgWarningTHD)
                 && (bmsInf->I_system  >  - bmsInf->SysParamStru.Ip_DsgOpenTHD)
                 && (bmsInf->sysAlarmStru.dsg_over_current != LEVEL1))           /* 放电告警*/
        {
            bmsInf->sysAlarmStru.dsg_over_current = LEVEL2;                  
        }
        else
        {       
            if (bmsInf->sysAlarmStru.dsg_over_current == LEVEL2)
                bmsInf->sysAlarmStru.dsg_over_current = NORMAL;
        }
    }
}

/**
  * @brief  检测soc
  * @attention
  * @retval 无
**/
void check_soc_alarm_task(void)
{
    _SystemDataStru *bmsInf = getBmsInf();

    uint16_t  soc;
    soc = bmsInf->SOC;
    if (bmsInf->workMode != MODE_CHG)/*充电模式不进行soc报警检测*/
    {
        if (soc < bmsInf->SysParamStru.SOC_L1THD)
        {
            bmsInf->sysAlarmStru.low_soc = LEVEL1;
        }
        else if ((soc <= bmsInf->SysParamStru.SOC_L2THD)
                 && (soc > bmsInf->SysParamStru.SOC_L1THD))
        {
            bmsInf->sysAlarmStru.low_soc = LEVEL2;
        }
        else if ((soc <= bmsInf->SysParamStru.SOC_L3THD)
                 && (soc > bmsInf->SysParamStru.SOC_L2THD))
        {
            bmsInf->sysAlarmStru.low_soc = LEVEL3;
        }
        else
        {
            bmsInf->sysAlarmStru.low_soc = NORMAL;
        }
    }
    else
    {
        bmsInf->sysAlarmStru.low_soc = NORMAL;
    }
}


/**
  * @brief  检测温度过高或过低
  * @attention 运行周期50ms
  * @retval 无
**/
void check_T_alarm_task(void)
{
    _SystemDataStru *bmsInf = getBmsInf();

    if ((bmsInf-> deltaT >= (bmsInf->SysParamStru.deltaT_WarningTHD))
             && (bmsInf-> deltaT < (bmsInf->SysParamStru.deltaT_OpenTHD))
             && (bmsInf->sysAlarmStru.delta_t != LEVEL1))
    {
        bmsInf->sysAlarmStru.delta_t = LEVEL2;
    }
    else
    {
        if (bmsInf->sysAlarmStru.delta_t == LEVEL2)
            bmsInf->sysAlarmStru.delta_t = NORMAL;
    }
    if (bmsInf->workMode == MODE_CHG)/*充电模式*/
    {
        if ((bmsInf->Tmax >= (bmsInf->SysParamStru.ChgOTWarningTHD + T_OFFSET))
                 && (bmsInf->Tmax < (bmsInf->SysParamStru.ChgOTOpenTHD + T_OFFSET))
                 && (bmsInf->sysAlarmStru.chg_over_T != LEVEL1))
        {
            bmsInf->sysAlarmStru.chg_over_T = LEVEL2;
        }
        else
        {
            if (bmsInf->sysAlarmStru.chg_over_T == LEVEL2)
                bmsInf->sysAlarmStru.chg_over_T = NORMAL;
        }
        /*充电欠温检测*/

        if ((bmsInf->Tmin < (bmsInf->SysParamStru.chg_ut_l2 + T_OFFSET))
                 && (bmsInf->Tmin > (bmsInf->SysParamStru.chg_ut_l1 + T_OFFSET))
                 && (bmsInf->sysAlarmStru.chg_ut != LEVEL1))
        {
            bmsInf->sysAlarmStru.chg_ut = LEVEL2;
        }
        else /*充电不欠温*/
        {
            if (bmsInf->sysAlarmStru.chg_ut == LEVEL2)
                bmsInf->sysAlarmStru.chg_ut = NORMAL;
        }
    }
    else/*放电模式和故障模式处理*/
    {
        if ((bmsInf->Tmax >= (bmsInf->SysParamStru.DsgOTWarningTHD + T_OFFSET))
                 && (bmsInf->Tmax < (bmsInf->SysParamStru.DsgOTOpenTHD + T_OFFSET))
                 && (bmsInf->sysAlarmStru.dsg_over_T != LEVEL1))
        {
            bmsInf->sysAlarmStru.dsg_over_T = LEVEL2;
        }
        else /*放电不过温*/
        {
            if (bmsInf->sysAlarmStru.dsg_over_T == LEVEL2)
                bmsInf->sysAlarmStru.dsg_over_T = NORMAL;
        }
        if ((bmsInf->Tmin < (bmsInf->SysParamStru.DsgUTWarningTHD + T_OFFSET))
                 && (bmsInf->Tmin > (bmsInf->SysParamStru.DsgUTOpenTHD + T_OFFSET))
                 && (bmsInf->sysAlarmStru.dsg_ut != LEVEL1))
        {
            bmsInf->sysAlarmStru.dsg_ut = LEVEL2;
        }
        else /*放电不欠温*/
        {
            if (bmsInf->sysAlarmStru.dsg_ut == LEVEL2)
                bmsInf->sysAlarmStru.dsg_ut = NORMAL;
        }
    }
}


/**
  * @brief  检测单体电压过高或过低
  * @attention 运行周期50ms
  * @retval 无
**/
void check_cell_vol_alarm(void)
{
    _SystemDataStru *bmsInf = getBmsInf();
    uint16_t vmax = bmsInf->VcellMax;
    uint16_t vmin = bmsInf->VcellMin;
    if ((bmsInf->Vdelta_Cell >= bmsInf->SysParamStru.deltaVolWarningTHD)
             && (bmsInf->Vdelta_Cell  < bmsInf->SysParamStru.deltaVolOpenTHD)
             && (bmsInf->sysAlarmStru.delta_v != LEVEL1))
    {
        bmsInf->sysAlarmStru.delta_v = LEVEL2;
    }
    else
    {
        if (bmsInf->sysAlarmStru.delta_v == LEVEL2)
            bmsInf->sysAlarmStru.delta_v = NORMAL;
    }
    if ((vmax >= bmsInf->SysParamStru.cellOverVolWaringTHD)
             && (vmax < bmsInf->SysParamStru.cellOverVolOpenTHD)
             && (bmsInf->sysAlarmStru.cell_ov != LEVEL1))
    {

        bmsInf->sysAlarmStru.cell_ov = LEVEL2;
    }
    else
    {
        if (bmsInf->sysAlarmStru.cell_ov == LEVEL2)
            bmsInf->sysAlarmStru.cell_ov = NORMAL;
    }
    if ((vmin <= bmsInf->SysParamStru.cellUnderVolWarningTHD)
              && (vmin > bmsInf->SysParamStru.cellUnderVolOpenTHD)
              && (bmsInf->sysAlarmStru.cell_uv != LEVEL1))
    {
        bmsInf->sysAlarmStru.cell_uv = LEVEL2;
    }
    else
    {
        if (bmsInf->sysAlarmStru.cell_uv == LEVEL2)
        {
            bmsInf->sysAlarmStru.cell_uv = NORMAL;
        }
    }
}

/**
 * @brief 
 * 
 */
void checkAlarmTask(void)
{
    check_pack_vol_alarm_task();
    check_I_alarm_task();
    check_soc_alarm_task();
    check_T_alarm_task();
    check_cell_vol_alarm();

}